package client;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.text.*;
import javax.swing.text.html.*;
import org.jdesktop.jdic.browser.*;

/**
 * AIM Window. Lots of fun stuff in here
 * Team 9: Andrew Hayworth, Brian Parrella, Ryan Kortmann, Nina Papa
 * @author Andrew Hayworth
 */

public class ChatWindow {
	private JFrame jf;
	private String from;
	private JPanel jp;
	private JScrollPane jsp;
	private JTextField jtf;
	private JButton send;
	private JEditorPane jep;
	private boolean allowSendTyp = true;
	private long lastKeyPress = 0;
	
	// this gui code has been known to cause cancer to the state of california.
	public ChatWindow(String f) {
		jf = new JFrame();
		this.from = f;
		jp = new JPanel();
		send = new JButton("Send");
		send.setMnemonic('S');
		jtf = new JTextField(20);
		jp.add(jtf);
		jp.add(send);
		jf.add(jp, BorderLayout.SOUTH);
;
		jep = new JEditorPane();
		jep.setEditable(false);
		jep.setContentType("text/html");

		jsp = new JScrollPane(jep);
		jsp.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
		jsp.setAutoscrolls(false);
		jf.add(jsp, BorderLayout.CENTER);
		jf.setSize(400,400);
		jf.setLocationRelativeTo(null);
		jf.setTitle("Chat with " + from);
		jf.setVisible(true);
		jtf.requestFocusInWindow();
		
		jf.addWindowListener( new WindowAdapter() {
			public void windowClosing(WindowEvent we) {
				AIM.chats.remove(from);
				jf.dispose();
			}
		});
		
		// sends our message to teh internets.
		send.addActionListener( new ActionListener() {
			public void actionPerformed(ActionEvent ae) {
				AIM.jtoc2.send(from, jtf.getText());
				AIM.jtoc2.sendTypingNotifications(from, 0);	// tells them we've sent text, and are not typing more currently.
				try {
					// we have to render as html because a lot of AIM clients send messages as strings of html
					// unfortunately they often send TERRIBLE html. which sucks.
					// we do the best we can with it.
					HTMLEditorKit hek = new HTMLEditorKit();
					hek.insertHTML((HTMLDocument)jep.getDocument(), 0 , (AIM.uname + ": " + jtf.getText() + "</br>"), 1, 0, HTML.Tag.BODY);
					// this, as a side effect, puts our new message at the top. 
					// i've tried setting autoscroll(false), but the damn window still scrolls.
					// so we try to keep it at the top. which helps, but it's still broken and quite honestly i hate
					// swing so much that i dont want to fix it.
					jsp.getViewport().setViewPosition(new java.awt.Point(0, 0));
					
					jtf.setText("");
					jtf.requestFocusInWindow();
					TTClient.playMsgOut();
				}
				catch (Exception e) {}
				allowSendTyp = true;	// we can start a typing notification thread again!
			}
		});
		
		jtf.addKeyListener( new KeyAdapter() {
			public void keyReleased(KeyEvent ke) {
				if (ke.getKeyCode() == KeyEvent.VK_ENTER) {
					send.doClick();	// thank you, swing.
				}
				// update the last keypress time
				lastKeyPress = System.currentTimeMillis();
				// here we kick off a timer of sorts.... 
				// this may be duplicating functionality in timertask, but this made more sense to me at the time
				// if we're allow to send typing notifications (ie, they have recently clicked the send button
				if (allowSendTyp) {
					// then we kick off a thread
					(new Thread() {
						public void run() {
							// which immediately blocks any other threads from being kicked off until they've sent the current message
							allowSendTyp = false;
							// while they have not clicked send
							while (!(allowSendTyp)) {
								
								// if allowSendTyp has switched to true, IMMEDIATELY GTFO.
								//otherwise, people who send a lot of messages get a lot of typing notification threads
								// then they get disconnected for spamming the aol servers :)
								if (allowSendTyp) return;
								
								// send them a paused typing notification message if its been greater than 5 seconds
								if (System.currentTimeMillis() > lastKeyPress + 5000) {
									AIM.jtoc2.sendTypingNotifications(from, 1);
									allowSendTyp = true;
								}
								// otherwise send them a typing notification mesage
								else { 
									AIM.jtoc2.sendTypingNotifications(from, 2);
								}
								//then we sleep for one second
								try {Thread.sleep(3000);}
								catch (InterruptedException e) {}
							}	// this loop will only run while they have not clicked send.
						}
					}).start();
				}
			}
		});
	}
	
	/**
	 * Updates the chat window when we get a new IM_IN2: message from toc2
	 * @param msg What they said.
	 */
	public void updateChat(String msg) {
		try {
			// we have to render as html because a lot of AIM clients send messages as strings of html
			// unfortunately they often send TERRIBLE html. which sucks.
			// we do the best we can with it.
			HTMLEditorKit hek = new HTMLEditorKit();
			hek.insertHTML((HTMLDocument)jep.getDocument(), 0 , (from + ": " + msg + "</br>"), 1, 0, HTML.Tag.BODY);
			jsp.getViewport().setViewPosition(new java.awt.Point(0, 0));
			TTClient.playMsgIn();
			
		}
		catch (Exception e) {}
	}
	
	/**
	 * Updates the chat window with what they said
	 * @param name Who said it?
	 * @param msg What did they say?
	 */
	public void updateChat(String name, String msg) {
		try {
			// i think i've ranted enough at this point. you know what this code does.
			// should be abstracted away into a method at some point before the apocalypse
			HTMLEditorKit hek = new HTMLEditorKit();
			hek.insertHTML((HTMLDocument)jep.getDocument(), 0, (name + ": " + msg + "</br>"), 1, 0, HTML.Tag.BODY);
			jsp.getViewport().setViewPosition(new java.awt.Point(0, 0));
			TTClient.playMsgIn();
		}
		catch (Exception e) {}
	}
	
	/**
	 * Tries to bring the window to the front
	 */
	public void alert() {
		jf.requestFocus();
	}
}
